# coding: utf-8
import subprocess
from pathlib import Path
from typing import Union, List, Literal


class Qrc:
    """
    从源目录生成 qrc文件
    Generate qrc file from source directory.
    """

    def __init__(
            self,
            source_dir: Union[str, Path],
            prefix: str,
            qrc_file: Union[str, Path],
            skip: List[str] = None,
            to_py: bool = False,
            py_path: Union[str, Path] = None,
            qt_type: Literal['PySide2', 'PySide6', 'PyQt5', 'PyQt6'] = 'PySide6'
    ):
        """
        初始化 Qrc 对象
        :param source_dir: 源文件目录
        :param prefix: qrc文件前缀 eg: <qresource prefix="/element"> prefix="/element"
        :param save_to: 保存的 qrc 文件路径
        :param skip: 跳过的文件后缀 eg: ['.qrc', '.py']
        :param to_py: 是否生成 py 文件
        :param py_path: qrc转换为 py 文件保存路径
        :param qt_type: qt类型
        """
        if isinstance(source_dir, str):
            source_dir = Path(source_dir)
        self.source_dir = source_dir
        if not prefix.startswith('/'):
            prefix = '/' + prefix
        self.prefix = prefix
        if isinstance(qrc_file, str):
            qrc_file = Path(qrc_file)
        self.qrc_file = qrc_file
        if skip is None:
            skip = ['.qrc', '.py']
        self.skip = skip
        self.to_py = to_py
        if py_path is None:
            py_path = self.qrc_file.with_suffix('.py')
        self.py_path = py_path
        if qt_type == 'PySide2':
            self.qt_type = 'pyside-rcc'
        elif qt_type == 'PySide6':
            self.qt_type = 'pyside6-rcc'
        elif qt_type == 'PyQt5':
            self.qt_type = 'pyrcc5'
        elif qt_type == 'PyQt6':
            self.qt_type = 'pyrcc6'
        else:
            raise ValueError(f'Invalid qt_type: {qt_type}')

    def generate(self):
        rcc_list = []
        for file in self.source_dir.glob('**/*'):
            if file.suffix in self.skip:
                continue
            if file.is_dir():
                continue
            re_file = file.relative_to(self.source_dir).as_posix()
            print(f'Add {re_file} to qrc file')
            rcc_list.append(f'        <file>{re_file}</file>\n')
        rcc = ''.join(rcc_list)
        rcc = rcc.strip()
        self.qrc_file.write_text(
            f'''<RCC>
    <qresource prefix="{self.prefix}">
{rcc}
    </qresource>
</RCC>
'''
        )
        if self.to_py:
            self.qrc2py()

    def qrc2py(self) -> bool:
        process = subprocess.Popen(
            [self.qt_type, self.qrc_file.as_posix(), '-o', self.py_path.as_posix()],
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        out, err = process.communicate()
        if process.returncode != 0:
            print(f'Error: {err.decode()}')
            return False
        return True
